package com.ruoyi.purchase.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.purchase.domain.PurchaseOrdersDetails;
import com.ruoyi.purchase.dto.GenerateBoxCodeDTO;
import com.ruoyi.purchase.mapper.PurchaseOrdersMapper;
import com.ruoyi.purchase.vo.BoxCodesVO;
import com.ruoyi.system.domain.Items;
import com.ruoyi.system.mapper.ItemsMapper;
import com.ruoyi.system.service.impl.ItemsServiceImpl;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.purchase.mapper.BoxCodesMapper;
import com.ruoyi.purchase.domain.BoxCodes;
import com.ruoyi.purchase.service.IBoxCodesService;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.Max;

/**
 * 箱码列表Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-10-18
 */
@Service
public class BoxCodesServiceImpl implements IBoxCodesService 
{
    @Autowired
    private BoxCodesMapper boxCodesMapper;
    @Autowired
    private ItemsMapper itemsMapper;
    @Autowired
    private PurchaseOrdersMapper purchaseOrdersMapper;

    /*
       并发问题，如果多个用户同时请求生成箱码？
       1.同步加锁synchronized
       2.异步使用分布式锁或者redis序列号生成
       3.先查找数据库获取第一个箱码，如果出现包含相同则避免再增加

       本次箱码增加
       1.先查找数据库获取第一个箱码，再generateAndSaveBoxCodes循环增加
       2.先查找数据库获取第一个箱码，再generateBoxCode循环增加
     */

    /**
     * 根据采购订单号查询未发货的箱码
     */

    @Override
    public List<BoxCodesVO> UnshippedBoxCodesByPoId(String poId) {
        return boxCodesMapper.selectUnshippedBoxCodesByPoId(poId);
    }

    @Override
    public synchronized  String generateBoxCode() {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String datastr=sdf.format(new Date());
        String prefix="CG"+datastr;
        String maxBoxCode=boxCodesMapper.selectMaxBoxCodeByDate(prefix);
        int sequence = 1;
        if(maxBoxCode!=null){
            String sequenceStr =maxBoxCode.substring(prefix.length(),maxBoxCode.length());
            sequence =Integer.parseInt(sequenceStr)+1;

        }
        return String.format("%s%05d", prefix, sequence);

    }

    @Override
    public String generateBatchCode() {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String datastr=sdf.format(new Date());
        String maxBatchCode=boxCodesMapper.selectMaxBatchCodeByDate(datastr);
        int sequence = 1;
        if(maxBatchCode!=null){
            String sequenceStr =maxBatchCode.substring(datastr.length(),maxBatchCode.length());
            sequence =Integer.parseInt(sequenceStr)+1;

        }
        return String.format("%s%03d", datastr, sequence);
    }

    @Override
    public List<BoxCodesVO> selectBoxCodesListVO(BoxCodes boxCodes) {
        return boxCodesMapper.selectBoxCodesListVO(boxCodes);
    }

    @Override
    @Transactional
    public AjaxResult generateAndSaveBoxCodes(GenerateBoxCodeDTO dto) {
        System.out.println("生成箱码"+dto);
        try {
        Items items = itemsMapper.selectItemsByItemId(dto.getItemId());
        if(items==null){
            return AjaxResult.success("存货信息不存在");
        }
        //打码数量除以箱码数量是当前打了几箱
        Long boxCount=dto.getCodeNum()/dto.getBoxNum();
        if (dto.getCodeNum() % dto.getBoxNum() != 0) {
            boxCount++; // 如果有余数，箱数加1
        }


        // 4. 为每一箱生成箱码
        List<BoxCodes> boxCodesList = new ArrayList<>();
        Long remainingQuantity = dto.getCodeNum(); // 剩余需要打码的数量
            String firstBoxCode = this.generateBoxCode();
            String datePrefix = firstBoxCode.substring(0, 10); // 前10位：CG20251025
            String sequenceStr = firstBoxCode.substring(10); // 后5位：00009
            int sequence = Integer.parseInt(sequenceStr);



        for (int i = 0; i < boxCount; i++) {
            // 生成箱码和批次号
            String batchCode=generateBatchCode();
            // 计算当前箱的实际数量（最后一箱可能不足标箱数量）
            Long currentBoxNum = (i == boxCount - 1) ? remainingQuantity : dto.getBoxNum();
            // 生成箱码：序列号递增
            String boxCode = datePrefix + String.format("%05d", sequence + i);
            // 创建箱码记录（只存储关联字段）
            BoxCodes boxCodes = new BoxCodes();
            //后端调生成的方法
            boxCodes.setBatch(batchCode);
            boxCodes.setBoxId(boxCode);

            //前端传来的数据的
            boxCodes.setPoId(dto.getPoId());
            boxCodes.setBoxNum(dto.getBoxNum());
            boxCodes.setItemId(dto.getItemId());
            boxCodes.setProductionDate(dto.getProductionDate());

            boxCodes.setBinId("");
            boxCodes.setInspectionStatus(0L);

            boxCodes.setWarehousingStatus(0L);
            boxCodes.setDeliveryStatus(0L);
            boxCodes.setReceivingStatus(0L);
            boxCodes.setCreatedAt(new Date());
            boxCodes.setCreatedPerson("供应商张经理");
            boxCodes.setUpdatedAt(new Date());

            boxCodesList.add(boxCodes);
            // 更新剩余数量
            remainingQuantity -= currentBoxNum;

        }
        System.out.println("箱码列表数据"+boxCodesList);
        // 5. 批量保存箱码记录
        if (!boxCodesList.isEmpty()) {
            for (BoxCodes boxCodes : boxCodesList) {
                boxCodesMapper.insertBoxCodes(boxCodes);
            }
        }


            PurchaseOrdersDetails purchaseOrdersDetails = purchaseOrdersMapper.selectDetailByPoIdAndItemId(dto.getPoId(),dto.getItemId());
            if (purchaseOrdersDetails != null) {
                purchaseOrdersDetails.setCodeNum(purchaseOrdersDetails.getCodeNum() + dto.getCodeNum());
                purchaseOrdersDetails.setNotcodeNum(purchaseOrdersDetails.getNotcodeNum() - dto.getCodeNum());
                purchaseOrdersDetails.setUpdatedAt(new Date());
                purchaseOrdersDetails.setItemId(purchaseOrdersDetails.getItemId());
                purchaseOrdersMapper.updateboxCodesPurchaseOrdersDetails(purchaseOrdersDetails);
                return AjaxResult.success("成功生成 " + boxCount + " 个箱码");
            }
            else {
                    return AjaxResult.error("采购订单详情不存在");
            }

        }
        catch (Exception e) {
                throw new RuntimeException("生成箱码失败: " + e.getMessage(), e);
            }



    }
    /**
     * 查询箱码列表
     * 
     * @param id 箱码列表主键
     * @return 箱码列表
     */
    @Override
    public BoxCodesVO selectBoxCodesById(Long id)
    {
        return boxCodesMapper.selectBoxCodesById(id);
    }

    /**
     * 查询箱码列表列表
     * 
     * @param boxCodes 箱码列表
     * @return 箱码列表
     */
    @Override
    public List<BoxCodes> selectBoxCodesList(BoxCodes boxCodes)
    {
        return boxCodesMapper.selectBoxCodesList(boxCodes);
    }

    /**
     * 新增箱码列表
     * 
     * @param boxCodes 箱码列表
     * @return 结果
     */
    @Override
    public int insertBoxCodes(BoxCodes boxCodes)
    {
        return boxCodesMapper.insertBoxCodes(boxCodes);
    }

    /**
     * 修改箱码列表
     * 
     * @param boxCodes 箱码列表
     * @return 结果
     */
    @Override
    public int updateBoxCodes(BoxCodes boxCodes)
    {
        return boxCodesMapper.updateBoxCodes(boxCodes);
    }

    /**
     * 批量删除箱码列表
     * 
     * @param ids 需要删除的箱码列表主键
     * @return 结果
     */
    @Override
    public int deleteBoxCodesByIds(Long[] ids)
    {
        return boxCodesMapper.deleteBoxCodesByIds(ids);
    }

    /**
     * 删除箱码列表信息
     * 
     * @param id 箱码列表主键
     * @return 结果
     */
    @Override
    public int deleteBoxCodesById(Long id)
    {
        return boxCodesMapper.deleteBoxCodesById(id);
    }
}
